# 矩阵综合运算
# 创建时间：2025.10.24
# 创建者：郭吉喆

# 颜色库
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m'
RESET = '\033[0m'

# 创建空矩阵（最多支持26个）
class Square:
    def __init__(self, name, isSquare, row, column, element):
        self.name = name
        self.isSquare = isSquare
        self.row = row
        self.column = column
        self.element = element
square_a = Square("a", False, 0, 0, {})
square_b = Square("b", False, 0, 0, {})
square_c = Square("c", False, 0, 0, {})
square_d = Square("d", False, 0, 0, {})
square_e = Square("e", False, 0, 0, {})
square_f = Square("f", False, 0, 0, {})
square_g = Square("g", False, 0, 0, {})
square_h = Square("h", False, 0, 0, {})
square_i = Square("i", False, 0, 0, {})
square_j = Square("j", False, 0, 0, {})
square_k = Square("k", False, 0, 0, {})
square_l = Square("l", False, 0, 0, {})
square_m = Square("m", False, 0, 0, {})
square_n = Square("n", False, 0, 0, {})
square_o = Square("o", False, 0, 0, {})
square_p = Square("p", False, 0, 0, {})
square_q = Square("q", False, 0, 0, {})
square_r = Square("r", False, 0, 0, {})
square_s = Square("s", False, 0, 0, {})
square_t = Square("t", False, 0, 0, {})
square_u = Square("u", False, 0, 0, {})
square_v = Square("v", False, 0, 0, {})
square_w = Square("w", False, 0, 0, {})
square_x = Square("x", False, 0, 0, {})
square_y = Square("y", False, 0, 0, {})
square_z = Square("z", False, 0, 0, {})

dic_square = {
    "a": square_a,
    "b": square_b,
    "c": square_c,
    "d": square_d,
    "e": square_e,
    "f": square_f,
    "g": square_g,
    "h": square_h,
    "i": square_i,
    "j": square_j,
    "k": square_k,
    "l": square_l,
    "m": square_m,
    "n": square_n,
    "o": square_o,
    "p": square_p,
    "q": square_q,
    "r": square_r,
    "s": square_s,
    "t": square_t,
    "u": square_u,
    "v": square_v,
    "w": square_w,
    "x": square_x,
    "y": square_y,
    "z": square_z
}

# 已定义矩阵的列表
sq_defined = []

# 矩阵定义
def define_square():
    define_name = str(input("定义矩阵名称（单个小写字母表示）--->"))
    try:
        dic_square[define_name]
    except KeyError:
        print(f"{RED}WARNING--定义不合法{RESET}")
    else:
        dic_square[define_name].element = {}
        dic_square[define_name].row = int(input("请输入矩阵行数--->"))
        dic_square[define_name].column = int(input("请输入矩阵列数--->"))
        if dic_square[define_name].row == dic_square[define_name].column:
            dic_square[define_name].isSquare = True
        # 输入数据
        for i in range(1, dic_square[define_name].row + 1):
            dic_square[define_name].element[i] = []
        row = 1
        while row <= dic_square[define_name].row:
            column = 1
            while column <= dic_square[define_name].column:
                while True:  # 防止用户误操作输入错误数据
                    num = input(f"输入第{row}行 第{column}列的数据--->")
                    if num == "":
                        pass
                    else:
                        break
                dic_square[define_name].element[row].append(num)
                column += 1
            row += 1
        # 数据类型改为float
        for i in range(1, dic_square[define_name].row + 1):
            dic_square[define_name].element[i] = list(map(float, dic_square[define_name].element[i]))

# 单位矩阵定义
def define_unit():
    define_name = str(input("定义单位矩阵名称（单个小写字母表示）--->"))
    try:
        square = dic_square[define_name]
    except KeyError:
        print(f"{RED}WARNING--定义不合法{RESET}")
    else:
        try:
            row = int(input("请输入阶数--->"))
        except:
            print(f"{RED}WARNING--定义不合法{RESET}")
        else:
            square.row = row
            square.column = row
            square.isSquare = True
            for i in range(1, row + 1):
                square.element[i] = []
                for j in range(1, row + 1):
                    square.element[i].append(0)
                    if i == j:
                        square.element[i][j - 1] = 1.0

# 零矩阵定义
def define_zero():
    define_name = str(input("定义零矩阵名称（单个小写字母表示）--->"))
    try:
        square = dic_square[define_name]
    except KeyError:
        print(f"{RED}WARNING--定义不合法{RESET}")
    else:
        try:
            row = int(input("请输入行数--->"))
            column = int(input("请输入列数--->"))
        except:
            print(f"{RED}WARNING--定义不合法{RESET}")
        else:
            square.row = row
            square.column = column
            if row == column:
                square.isSquare = True
            for i in range(1, row + 1):
                square.element[i] = []
                for j in range(1, row + 1):
                    square.element[i].append(0)

# 矩阵乘法
def multiple(square_1_name, square_2_name, square_3_name): # square_1 * square_2 = square_3
    square_1 = dic_square[square_1_name]
    square_2 = dic_square[square_2_name]
    square_3 = dic_square[square_3_name]
    if square_1.column != square_2.row:
        print(f"{RED}WARNING--无法运算{RESET}")
    else:
        # 输出矩阵定义
        square_3.row = square_1.row
        square_3.column = square_2.column
        square_3.element = {}
        if square_3.row == square_3.column:
            square_3.isSquare = True
        cycle = square_1.column
        for i in range(1, square_3.row + 1):
            square_3.element[i] = []
            for j in range(1, square_3.column + 1):
                element = 0
                for k in range(1, cycle + 1):
                    element += square_1.element[i][k - 1] * square_2.element[k][j - 1]
                square_3.element[i].append(element)

# 矩阵加减法
def plus(square_1_name, square_2_name, square_3_name, signal):
    square_1 = dic_square[square_1_name]
    square_2 = dic_square[square_2_name]
    square_3 = dic_square[square_3_name]
    if signal == "+":
        signal = 1.0
    elif signal == "-":
        signal = -1.0
    if square_1.row != square_2.row or square_1.column != square_2.column:
        print(f"{RED}WARNING--无法运算{RESET}")
    else:
        square_3.row = square_1.row
        square_3.column = square_1.column
        square_3.element = {}
        if square_3.row == square_3.column:
            square_3.isSquare = True
        for i in range(1, square_3.row + 1):
            square_3.element[i] = []
            for j in range(1, square_3.column + 1):
                element = square_1.element[i][j - 1] + signal * square_2.element[i][j - 1]
                square_3.element[i].append(element)

# 输出矩阵
def output():
    square_name = str(input("输入想要查询的矩阵名（单个小写字母表示）--->）"))
    try:
        square = dic_square[square_name]
    except KeyError:
        print(f"{RED}WARNING--输入不合法{RESET}")
    else:
        print(f"矩阵{YELLOW}{square.name}{RESET}结果如下：")
        for i in range(1, square.row + 1):
            for j in range(0, square.column):
                print(f"{square.element[i][j]:10.4f}", end="")  # 总宽度.保留小数位数
            print("\n")
        wait_for_check = input('\n按任意键继续--->')

# 求逆矩阵
def inverse(square, inverse_square):
    ROW = {}  # 行的集合
    n = square.row
    for i in range(1, n + 1):
        ROW[i] = []
    # print(inverse_square.element)
    # 输入原矩阵的数据
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            ROW[i].append(square.element[i][j - 1])
    # 添加单位矩阵
    row = 1
    while row <= n:
        cnt = 1
        while cnt <= n:
            ROW[row].append(0)  # 构造零矩阵
            cnt += 1
        ROW[row][n + row - 1] = 1  # 在零矩阵中添加1
        row += 1
    # 考虑到矩阵运算，需将列表所有元素转换为float类型
    for i in range(1, n + 1):
        ROW[i] = list(map(float, ROW[i]))
    # 初等变换（函数定义倍法变换，换法变换以及消法变换）
    def multi(row, mult):
        ROW[row] = list(map(lambda x: x * mult, ROW[row]))
    def change(row_1, row_2):
        row_mid = ROW[row_1]
        ROW[row_1] = ROW[row_2]
        ROW[row_2] = row_mid
    def minus(row_o, row_c, mult):  # 不动行，运算行，倍数
        for i in range(0, 2 * n):
            ROW[row_c][i] += ROW[row_o][i] * mult
    # 重复ab步骤
    for i in range(1, n + 1):
        min_row = 0
        for t in range(i, n + 1):  # 检索非零数
            if ROW[t][i - 1] != 0:
                min_row = t
                min_num = ROW[t][i - 1]
                change(i, min_row)
                break
        if min_row == 0:
            return None
        inverse_square.element = {}
        inverse_square.row = square.row
        inverse_square.column = square.column
        inverse_square.isSquare = True
        for j in range(i, n + 1):  # a.比较各行非零数，取绝对值最小数化为1
            if ROW[j][i - 1] == 0:
                continue
            if abs(ROW[j][i - 1]) < abs(min_num):
                min_row = j
                min_num = ROW[j][i - 1]
                change(i, min_row)
        multi(i, 1.0 / min_num)
        for k in range(1, n + 1):  # b.消法变换，在列上构造单位矩阵
            if k == i:
                continue
            minus(i, k, -ROW[k][i - 1])
    # 删去单位矩阵，得到逆矩阵
    for i in range(1, n + 1):
        for j in range(0, n):
            ROW[i].remove(ROW[i][0])
    # 保存逆矩阵
    for i in range(1, n + 1):
        inverse_square.element[i] = []
        for j in range(0, n):
            inverse_square.element[i].append(ROW[i][j])
    # print(inverse_square.name)
    # print(inverse_square.element)
    # print(square.name)
    # print(square.element)
    return inverse_square.element

# 求矩阵的幂
def exp_square(square, power_square, power):
    power_square.row = square.row
    power_square.column = square.column
    power_square.isSquare = True
    power_square.element = square.element
    cycle = square.row
    for h in range(1, power):
        mid_element = power_square.element
        power_square.element = {}
        for i in range(1, cycle + 1):
            power_square.element[i] = []
            for j in range(1, cycle + 1):
                element = 0
                for k in range(1, cycle + 1):
                    element += mid_element[i][k - 1] * square.element[k][j - 1]
                power_square.element[i].append(element)

# 矩阵组合
def combine_square():
    combine_row = {}
    standard_column = []
    try:
        big_row = int(input("请输入在一列中的矩阵数--->"))
        big_column = int(input("请输入在一行中的矩阵数--->"))
    except ValueError:
        print(f"{RED}WARNING--输入不合法{RESET}")
        return None
    else:
        # 输入矩阵
        for i in range(1, big_row + 1):
            combine_row[i] = []
            for j in range(1, big_column + 1):
                square_name = str(input(f"输入第{i}行 第{j}列的矩阵名称（单个小写字母表示）--->"))
                while True:  # 防止用户误操作输入错误矩阵
                    if square_name in sq_defined:
                        square = dic_square[square_name]
                        combine_row[i].append(square)
                        break
                    else:
                        square_name = str(input("--->"))
            # 对输入矩阵进行格式检查
            if i == 1:
                row_first = combine_row[1][0].row
                for k in combine_row[1]:
                    if k.row == row_first:
                        standard_column.append(k.column)
                        pass
                    else:
                        print(f"{RED}WARNING--无法组合{RESET}")
                        return None
            else:
                row_first = combine_row[i][0].row
                cnt = 0
                for k in combine_row[i]:
                    cnt += 1
                    if k.row == row_first:
                        if k.column == standard_column[cnt - 1]:
                            pass
                        else:
                            print(f"{RED}WARNING--无法组合{RESET}")
                            return None
                    else:
                        print(f"{RED}WARNING--无法组合{RESET}")
                        return None
        # 保存组合后的矩阵
        define_name = str(input("定义组合后矩阵的名称（单个小写字母表示）--->"))
        try:
            combined_square = dic_square[define_name]
        except KeyError:
            print(f"{RED}WARNING--定义不合法{RESET}")
            return None
        else:
            element = {}
            sum_row = 0
            sum_column = 0
            for i in range(1, big_row + 1):
                i_row = combine_row[i][0].row
                for j in range(0, big_column):
                    s = combine_row[i][j]
                    for k in range(sum_row + 1, sum_row + i_row + 1):
                        try:
                            element[k]
                        except KeyError:
                            element[k] = []
                        else:
                            pass
                        for l in range(0, s.column):
                            element[k].append(s.element[k - sum_row][l])
                sum_row += i_row
            for i in standard_column:
                sum_column += i
            combined_square.row = sum_row
            combined_square.column = sum_column
            combined_square.element = element
            if sum_row == sum_column:
                combined_square.isSquare = True
            # print(element)
            return None

# 主页面
def table():
    print(f"""---------{YELLOW}矩阵运算器{RESET}---------
1.{CYAN}定义{RESET}一个矩阵（可覆盖）
2.快速构造{CYAN}单位矩阵{RESET}（可覆盖）
3.快速构造{CYAN}零矩阵{RESET}（可覆盖）
4.{CYAN}输出{RESET}一个矩阵
5.进行两个矩阵的{CYAN}加减法{RESET}运算
6.进行两个矩阵的{CYAN}乘法{RESET}运算
7.进行单个方阵的{CYAN}幂{RESET}运算
8.求一个方阵的{CYAN}逆矩阵{RESET}
9.进行多个{YELLOW}已定义矩阵{RESET}的{CYAN}组合{RESET}""")
    print(f"\n{YELLOW}已定义矩阵{RESET}：", end="")
    for sq in dic_square.values():
        if sq.element == {}:
            pass
        else:
            sq_defined.append(sq.name)
            print(f"{YELLOW}{sq.name}{RESET}",end=" ")
    print("\ntip.输入数字进行相关操作")
    while True:
        operation = str(input("--->"))
        # 1.定义
        if operation == "1":
            define_square()
            break
        # 6.乘法运算
        elif operation == "6":
            formula = str(input("输入运算式（形如ab、ba等）--->"))
            s = []
            for i in formula:
                s.append(i)
            # 检验是否合法
            if len(s) == 2:
                try:
                    square_1 = dic_square[s[0]]
                    square_2 = dic_square[s[1]]
                except KeyError:
                    print(f"{RED}WARNING--输入不合法{RESET}")
                    break
                else:
                    square_3_name = str(input("输入储存结果的矩阵名（单个小写字母表示）（不可与算式中的矩阵重复）--->）"))
                    if square_3_name in [square_1.name, square_2.name]:
                        print(f"{RED}WARNING--输入不合法{RESET}")
                        break
                    else:
                        try:
                            square_3 = dic_square[square_3_name]
                        except KeyError:
                            print(f"{RED}WARNING--输入不合法{RESET}")
                            break
                        else:
                            multiple(square_1.name, square_2.name, square_3.name)
                            break
            else:
                print(f"{RED}WARNING--输入不合法{RESET}")
                break
        # 5.加减法运算
        elif operation == "5":
            formula = str(input("输入运算式（形如a+b、a-b等）--->"))
            s = []
            for i in formula:
                s.append(i)
            try:
                signal = str(s[1])
            except KeyError:
                print(f"{RED}WARNING--输入不合法{RESET}")
                break
            except IndexError:
                print(f"{RED}WARNING--输入不合法{RESET}")
                break
            else:
                if len(s) == 3 and signal in ["+", "-"]:
                    try:
                        square_1 = dic_square[s[0]]
                        square_2 = dic_square[s[2]]
                    except KeyError:
                        print(f"{RED}WARNING--输入不合法{RESET}")
                        break
                    else:
                        square_3_name = str(input("输入储存结果的矩阵名（单个小写字母表示）（不可与算式中的矩阵重复）--->）"))
                        if square_3_name in [square_1.name, square_2.name]:
                            print(f"{RED}WARNING--输入不合法{RESET}")
                            break
                        else:
                            try:
                                square_3 = dic_square[square_3_name]
                            except KeyError:
                                print(f"{RED}WARNING--输入不合法{RESET}")
                                break
                            else:
                                plus(square_1.name, square_2.name, square_3.name, signal)
                                break
                else:
                    print(f"{RED}WARNING--输入不合法{RESET}")
                    break
        # 4.查看矩阵
        elif operation == "4":
            output()
            break
        # 8.求逆矩阵（基于本人编写的求逆矩阵Plus.py）
        elif operation == "8":
            square_name = str(input("输入矩阵名称（单个小写字母表示）--->"))
            try:
                square = dic_square[square_name]
            except KeyError:
                print(f"{RED}WARNING--无法求逆{RESET}")
                break
            else:
                if square.isSquare:
                    inverse_square_name = str(input("输入储存结果的矩阵名（单个小写字母表示）（不可与原矩阵重复）--->）"))
                    if inverse_square_name == square_name:
                        print(f"{RED}WARNING--输入不合法{RESET}")
                        break
                    else:
                        try:
                            inverse_square = dic_square[inverse_square_name]
                        except KeyError:
                            print(f"{RED}WARNING--输入不合法{RESET}")
                            break
                        else:
                            result = inverse(square,inverse_square)
                            if result == None:
                                print(f"{RED}WARNING--矩阵行列式为零{RESET}")
                            else:
                                inverse_square.element = result
                            break
                else:
                    print(f"{RED}WARNING--无法求逆{RESET}")
                    break
        # 2.快速构造单位矩阵
        elif operation == "2":
            define_unit()
            break
        # 7.矩阵求幂
        elif operation == "7":
            square_name = str(input("输入矩阵名称（单个小写字母表示）--->"))
            try:
                square = dic_square[square_name]
            except KeyError:
                print(f"{RED}WARNING--无法求幂{RESET}")
                break
            else:
                if square.isSquare:
                    try:
                        power = int(input("输入幂的值（正整数）--->"))
                    except:
                        print(f"{RED}WARNING--输入不合法{RESET}")
                        break
                    else:
                        power_square_name = str(input("输入储存结果的矩阵名（单个小写字母表示）（不可与原矩阵重复）--->）"))
                        if power_square_name == square_name:
                            print(f"{RED}WARNING--输入不合法{RESET}")
                            break
                        else:
                            try:
                                power_square = dic_square[power_square_name]
                            except KeyError:
                                print(f"{RED}WARNING--输入不合法{RESET}")
                                break
                            else:
                                exp_square(square, power_square, power)
                                break
                else:
                    print(f"{RED}WARNING--无法求幂{RESET}")
                    break
        # 3.快速构造单位矩阵
        elif operation == "3":
            define_zero()
            break
        # 9.矩阵组合
        elif operation == "9":
            combine_square()
            break
        else:
            pass
# 运行
while True:
    table()
